<?php
JLoader::register("Upload", JPATH_SITE.'/components/com_easygallery/class.upload.php/class.upload.php');

JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_puser/tables');
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_jobs/tables');

/**
 * Registration controller class for Users.
 */
class PJobSeekerModelJobSeeker extends JModelLegacy
{
   public function getTable($name='', $prefix='PUserTable', $options = array()) {
      return JTable::getInstance($name, $prefix);
   }

   protected function loadUser($userid) {
      $db = PFactory::getDbo();

      $query = 'SELECT c.*, u.* ' .
         ' FROM #__users AS u' .
         ' LEFT JOIN #__comprofiler AS c ON c.user_id=u.id ' .
         ' WHERE u.block=0 AND u.id=' . intval($userid);
      $db->setQuery($query);
      return $db->loadObject();
   }

   protected function validateFields($fields=array()) {
      foreach($fields as $field => $value) {
         switch($field) {
            case 'name':
               if(JString::strlen($value) < 2 || JString::strlen($value) > 10) {
                  $this->setError("请输入一个长度为 2~10 的用户名");
                  return false;
               }
            break;
            case 'email':
               if(!JMailHelper::isEmailAddress($value)) {
                  $this->setError("请输入正确格式的电子邮件");
                  return false;
               }
            break;

            case 'password':
               if(!preg_match("/^[^\s]{6,255}$/i", $value)) {
                  $this->setError("请输入有效的密码，至少6个字符，可包含数字、字母或其他字符，不允许使用空格");
                  return false;
               }
            break;

            case 'phone':
               if(strlen($value) > 0 && !JobHelper::isPhone($value)) {
                  $this->setError("请输入正确的联系电话");
                  return false;
               }
            break;
         }

      }

      return true;
   }

   /**
    * Method to log out a user.
    *
    * @since   1.6
    */
   public function logout() {
      $cookie_domain = PFactory::getConfig()->get('cookie_domain', '');
      $cookie_path = PFactory::getConfig()->get('cookie_path', '/');
      setcookie(PApplication::getHash('PLOGIN_REMEMBER'), false, time() - 86400, $cookie_path, $cookie_domain);

      OC_User::logout();
      header("Location: " . OC::$WEBROOT . '/');
   }

   /**
    * Method to register into Joomla Platform
    *
    */
   private function _register($data) {
      $config = PFactory::getConfig();
      $db      = PFactory::getDbo();

      // Initialise the table with JUser.
      $user = new JUser;

      // Get the groups the user should be added to after registration.
      $data['groups'] = array();

      // Get the default new user group, Registered if not specified.
      $params  = JComponentHelper::getParams('com_users');
      $data['groups'][] = $params->get('new_usertype', 2);

      // Get usertype
      $query  = 'SELECT title AS name FROM #__usergroups WHERE id = ' . intval($params->get('new_usertype', 2));
      $db->setQuery($query);
      $data['usertype'] = $db->loadResult();

      // Bind the data.
      if (!$user->bind($data)) {
         $this->setError("绑定注册数据失败: " . $user->getError());
         return false;
      }

     // Store the data.
      if (!$user->save()) {
         $this->setError("保存注册数据失败: " . $user->getError());
         return false;
      }

      return $user;
   }

   /**
    * Method to register a user.
    * @param  bool  $is_mobile Set true if called by mobile api
    * @since   1.6
    */
   public function register($is_mobile=false) {
      /* disable token to avoid session timeout issue - we have captcha protection 
      // simple security check
      if(!PSession::checkToken()) {
         $this->setError('非法的系统安全码');
         return false;
      }
      */

      $db  =  PFactory::getDbo();
      $app =  PFactory::getApplication();

      $email = JRequest::getString("email", "");
      $password =  JRequest::getString("password", "");

      // Get the form data.
      $data   = JRequest::get('post');

      $vcode = JRequest::getString("vcode", "");
      
      $baseinfo = $app->getUserState("jobseeker_registers_basicinfo");

      if(empty($baseinfo)) {
         /* don't check vcode if it's local post, or in dev mode or is referred user */
         if(!$is_mobile && !isDevMode() && !isTestMode() && !JobHelper::checkEmailVcode($vcode,$email)) {
            $this->setError("错误的邮箱验证码");
            return false;
         }
      }

      // check to see if registration is from online interview result page 
      $token = $app->getUserState("interview_token");
      $has_verified_token = $app->getUserState("has_verified_token_".$token);
      
      // skip captcha is it has verified token in session - from direct jobseeker form registration 
      if(!$is_mobile && !isDevMode() && !$has_verified_token) {
         $needcaptcha = $app->getUserState("register_failed_captcha", false);
         if($needcaptcha) {
            /* captch is enforced. */
            $securimage = new Securimage();
            if($securimage->check(JRequest::getString("captcha_code", '')) == false) {
               jexit(jsonError("输入的安全码与图片显示不符,请重新输入<captcha_code></captcha_code>"));
            }
         }
      }

      if(!isset($data['acceptedterms'])) {
         $this->setError("您必须接受服务条款才能注册");
         return false;
      }

      // validate each input field
      if(!$this->validateFields($data))
         return false;
     
     // obtain information direct from verified token if it's set 
      if(!empty($baseinfo) && $has_verified_token) {
         $data['name'] = $baseinfo->jobseeker_name;
         $data['email'] = $baseinfo->jobseeker_email;
         $email = $baseinfo->jobseeker_email;
      }   
         
      $validmsg = JobHelper::validateEmail($email);
      if($validmsg !== true) {
         $this->setError($validmsg);
         return false;
      }

      //we need to record correct ip address based on async local request or direct register
      if(isLocalRequest() && isset($_POST['registeripaddr']))
         $data['registeripaddr']    =  $_POST['registeripaddr'];
      else
         $data['registeripaddr'] = getUserIp();

      $data['cb_usertype']          =  'jobseeker';

      // pre-set username to be email
      $data['username'] = $email;

      // when we reach here, we are safe to create users. first register into Joomla platform
      $user = $this->_register($data);
      if($user === false) {
         return false;
      }

      // make sure the id is same with user_id too
      $data['id'] = $user->id;

      // okay. good to update comprofiler table
      $table = $this->getTable('Comprofiler');
      /* first trying to load existing entires, so later store can decide to insert or update */
      if(!$table->load($user->id)) {
         /* it's a new row. We need to populate the row first otherwise the key field won't be able to set */
         $table->user_id = $user->id;
         $table->id = $user->id;
         $table->getDbo()->insertObject($table->getTableName(), $table);
         /* alternatively, one can use _getList example in JModel to build row */
      }

      // save the changes
      if (!$table->save($data)) {
         $this->deleteUser($user);
         $this->setError($table->getError());
         return false;
      }

      $table->name = $user->name;
      // initiate other user related tables
      if(!$this->saveRegistration($table)) {
         $this->deleteUser($table);
         return false;
      }

      if(!$this->directLogin($email, $password)) {
         $this->deleteUser($table);
         $this->setError("系统错误，请稍后再试！");
         return false;
      }

      // success: update login activity for jobseeker login
      JobHelper::setLastLogonDate($user);

      return $table;
   }

   public function directLogin($email, $password) {
      if (empty($email) || empty($password)) {
         return false;
      }

      $post = JRequest::get("post");
      OC_App::loadApps();

      //setup extra user backends
      OC_User::setupBackends();

      if (OC_User::login($email, $password)) {
         // setting up the time zone
         if (isset($post['timezone-offset'])) {
            $_SESSION['timezone'] = $post['timezone-offset'];
         }

         if (!empty($post["remember_login"])) {
           if (defined("DEBUG") && DEBUG) {
               OC_Log::write('core', 'Setting remember login to cookie', OC_Log::DEBUG);
            }

            // Create the encryption key, apply extra hardening using the user agent string.
            $privateKey = PApplication::getHash(@$_SERVER['HTTP_USER_AGENT']);

            $key = new JCryptKey('simple', $privateKey, $privateKey);
            $crypt = new JCrypt(new JCryptCipherSimple, $key);
            $credentials = array('username'=>$email, 'password'=>$password);
            $rcookie = $crypt->encrypt(serialize($credentials));
            $lifetime = time() + 365 * 24 * 60 * 60;

            // Use domain and path set in config for cookie if it exists.
            $cookie_domain = PFactory::getConfig()->get('cookie_domain', '');
            $cookie_path = PFactory::getConfig()->get('cookie_path', '/');
            setcookie(PApplication::getHash('PLOGIN_REMEMBER'), $rcookie, $lifetime, $cookie_path, $cookie_domain);
         }
      }
      return true;
   }

   /**
    * Method to log in a user.
    */
   public function login() {
      /* disable token to avoid session timeout issue 
      if(!PSession::checkToken('post')) {
         $this->setError('非法的系统安全码');
         return false;
      }
      */

      $app = PFactory::getApplication();

      /* captch is enforced. Before sending email, check captch. We have put it here as any success check will invalidate current code */
      if(!isDevMode()) {
         $needcaptcha = $app->getUserState("login_failed_captcha", false);
         if($needcaptcha) {
            $securimage = new Securimage();
            if($securimage->check(JRequest::getString("captcha_code", '')) == false) {
               jexit(jsonError("输入的安全码与图片显示不符,请重新输入<captcha_code></captcha_code>"));
            }
         }
      }

      $username = JRequest::getString("username", "");
      $password = JRequest::getString("password", "");

      /* perform form login directly; the remember login is controlled by handleRequest */
      $this->directLogin($username, $password);

      if(!OC_User::isLoggedIn()) {
         $this->setError('用户名和密码不匹配');
         return false;
      }

      $user = PFactory::getUser();
      // user chould be not valid as if the logged user is jobseeker 
      if(!$user->get("guest")) {
         JobHelper::setLastLogonDate($user);
         // Event Driven Cache/Object Caching - clear any cache related to affected tables 
         CacheHelper::triggerRemove($user->id, array('#__comprofiler'));
      }

      return true;
   }

   /*
    * save register
    */
   public function saveRegistration($user) {
      $db = PFactory::getDbo();
      $post = JRequest::get('post');
      $task = JRequest::getString("task");

      // Update jos_comprofiler
      $query = "UPDATE #__comprofiler SET
         `address` = ".$db->quote($user->address).",
         `phone` = ".$db->quote($user->phone).",
         `city` = ".$db->quote($user->city).",
         `id_city` = ".intval($user->id_city).",
         `state` = ".$db->quote($user->state).",
         `id_state` = ".intval($user->id_state)."
         WHERE `id` =".$user->id;

      $db->setQuery($query);
      if (!$db->execute()) {
         return false;
      }

      return true;
   }

   private function deleteUser($user) {
      $table = $this->getTable('Comprofiler');
      $table->delete($user->id);

      $user = PFactory::getUser($user->id);
      if($user)
         $user->delete();
   }
   
   public function needJob($email,$user_id='0') {
       $db = PFactory::getDbo();
   
       $query = 'SELECT j.*, e.comp_name, tk.token, tk.auto_send, js.specialization, jje.exp_name, jst.salary_type, hr.online_interview_progress,hr.online_interview_completion,'.
               'hr.match_degree,ppr.end_time as personcreated,ppr.id as testedid,ppr.sheetid as sheetid,ppr.date_diff,hr.is_new,ps.title as persontitle,pj.sheetid,jjp.position ' .
               ' from *PREFIX*hr_jobseeker as hr '.
               ' left join #__jobs_job as j on j.id=hr.job_id '.
               ' left join #__jobs_employer as e on e.user_id=j.employer_id '.
               ' left join #__users as u on u.id=e.user_id '.
               ' left join *PREFIX*hr_jobseeker_token as tk on tk.jobseeker_id=hr.id AND tk.disable=0 '.
               ' left join #__persontest_jobsheet as pj on pj.jobid=hr.job_id '.
               ' left join #__persontest_sheet as ps on ps.id=pj.sheetid '.
               ' left join (select id,end_time,sheetid,DATEDIFF(UTC_TIMESTAMP(),end_time) AS date_diff from #__persontest_result WHERE user_id= '.intval($user_id) .' GROUP BY sheetid ORDER BY end_time DESC) as ppr on ppr.sheetid=pj.sheetid '.
               ' left join #__jobs_job_spec as js on j.id_job_spec_categ=js.id '.
               ' left join #__jobs_job_exp as jje on jje.id=j.id_job_exp '.
               ' left join #__jobs_salary_type as jst on jst.id=j.id_salary_type '.
               ' left join #__jobs_job_position as jjp on jjp.id=j.id_pos_type '.
               ' WHERE hr.email=' . $db->quote($email).' AND j.id IS NOT NULL AND hr.company_id <> 0 AND u.block=0 AND j.system=0 '.
               ' AND e.comp_name NOT LIKE "PPPtest%"' . 
               ' AND u.email NOT LIKE "%pipapaitest.com"' .
               ' group by hr.id';

       $db->setQuery(PUtil::replaceOCPrefix($query));
       return $db->loadObjectList();
   }
   
   public function join($token) {
      $db = PFactory::getDbo();

      $query = 'SELECT j.email '.
               ' from *PREFIX*hr_jobseeker_token as tk '.
               'left join *PREFIX*hr_jobseeker as hr on tk.jobseeker_id=hr.id '.
               'left join #__users as j on j.email=hr.email '.
               'where tk.token=' . $db->quote($token);

      $db->setQuery(PUtil::replaceOCPrefix($query));
      $result = $db->loadAssoc();

      if (empty($result)) {
         // Try mobile
         $query = 'SELECT m.mobile AS email '.
                  ' from *PREFIX*hr_jobseeker_token as tk '.
                  'left join *PREFIX*hr_jobseeker as hr on tk.jobseeker_id=hr.id '.
                  'left join #__users_mobile as m on m.mobile=hr.phone '.
                  'where tk.token=' . $db->quote($token);

         $db->setQuery(PUtil::replaceOCPrefix($query));
         $result = $db->loadAssoc();
      }
      return $result;
   }

   /**
    * Save user settings
    * @param  bool  $is_mobile Set true if called by mobile api
    * @return bool
    */
   public function saveSettings($is_mobile=false) {
       // simple security check
       if(!$is_mobile && !PSession::checkToken()) {
           $this->setErrorCode(20004);
           $this->setError('登录已失效，请重新登录');
           return false;
       }
   
       if(!PFactory::isJobseekerUser()) {
           $this->setErrorCode(20006);
           $this->setError("您无权访问该资源");
           return false;
       }
   
       $me = PFactory::getUser();
       $userid = JRequest::getInt("uid", 0);
       $userid = $userid ? $userid : $me->id;
       $isOwner = $me->id == $userid;
       $puser = $this->loadUser($userid);
       if(!$puser) {
           $this->setErrorCode(20007);
           $this->setError("用户不存在");
           return false;
       }
    
       $post = JRequest::get('post');
   
       // validate each input field
       if(!$this->validateFields($post))
           return false;
       if(!$this->validateFields(array("password"=>$post["newpassword"]))) {
          return false;
       }   
       /* let's check whether this is passwd change */
       if(isset($post['currentpassword'])) {
           // validate current password
           $parts   = explode( ':', $puser->password );
           $crypt   = $parts[0];
           $salt = @$parts[1];
           $testcrypt = JUserHelper::getCryptedPassword($post['currentpassword'], $salt);
   
           if($crypt != $testcrypt) {
               $this->setErrorCode(20008);
               $this->setError("当前密码错误");
               return false;
           }
   
           if($post['newpassword'] != $post['newpassword_verify']) {
               $this->setErrorCode(20009);
               $this->setError("密码和验证密码不一致，请重试.");
               return false;
           }
   
           /* update password */
           $post['password'] = $post['newpassword'];
           $post['password2'] = $post['newpassword'];
       }
   
   
       /* save users information */
       $user = PFactory::getUser($puser->id);
       // Bind the data.
       if (!$user->bind($post)) {
           $this->setErrorCode(20010);
           $this->setError("绑定设置数据失败: " . $user->getError());
           return false;
       }
   
       // Store the data.
       if (!$user->save()) {
           $this->setErrorCode(20011);
           $this->setError("保存数据失败: " . $user->getError());
           return false;
       }
   
       return true;
   }

   public function setpersontest(){
       $db = PFactory::getDbo();
       $user = PFactory::getUser();
       $id = JRequest::getString('id');
       $jobid = JRequest::getString("jobid");
       /* update online_interview_progress; */
       PInterviewHelper::updateInterviewProgress('persontest', $user->id, $jobid);
       return true;       
   }

   public function loadjobseekerpersontest(){
      $db = PFactory::getDbo();
      $user = PFactory::getUser();
      $query = "SELECT  s.id, s.title, s.description, s.alias,
                (SELECT count(*) FROM #__persontest_result WHERE  user_id=".$user->id." AND sheetid=s.id) AS num,
                (SELECT TIMESTAMPDIFF(day, end_time, UTC_TIMESTAMP()) FROM #__persontest_result WHERE  user_id=".$user->id." AND sheetid=s.id) AS end_time_diff
                FROM #__persontest_sheet AS s";
      $db->setQuery(PUtil::replaceOCPrefix($query));
      return $db->loadObjectList();
   }

   public function getjobseekertestResultInfo($sheetid) {
      if (empty($sheetid))
         return null;
      $db = PFactory::getDbo();
      $user = PFactory::getUser();
      $query = "SELECT ps.title AS sheetTitle, pr.result, pr.start_time, pr.end_time
         FROM #__persontest_result AS pr
         LEFT JOIN #__persontest_sheet AS ps ON ps.id=pr.sheetid
         WHERE pr.user_id=".$user->id." AND pr.sheetid=".$sheetid." ORDER BY pr.id DESC LIMIT 1";
      $db->setQuery(PUtil::replaceOCPrefix($query));
      $persontestResultInfo = $db->loadObject();
      if(!empty($persontestResultInfo)) {
         $persontestResultInfo->result = json_decode($persontestResultInfo->result, true);
      }
      return $persontestResultInfo;
   }

   public function getPersontestAnswer($sheetalias, $pattern) {
   	if (empty($pattern))
   		return null;
   	 
   	$db = PFactory::getDbo();
   	 
   	if (is_array($pattern)) {
   		$patternArr = array();
   
   		foreach($pattern as $p)
   		{
   			$patternArr[] = $db->quote($p);
   		}
   
   		$query = "SELECT psp.title AS p_title, psp.text FROM #__persontest_sheet_patterns AS psp
                   LEFT JOIN #__persontest_sheet AS ps ON ps.id=psp.sheetid
                   WHERE ps.alias=".$db->quote($sheetalias)." AND psp.alias in (".implode(",", $patternArr).")"." AND psp.answer=1";
   		$db->setQuery($query);
   
   		return $db->loadObjectList();
   	} else {
   		$query = "SELECT psp.title AS p_title, psp.text FROM #__persontest_sheet_patterns AS psp
                   LEFT JOIN #__persontest_sheet AS ps ON ps.id=psp.sheetid
                   WHERE ps.alias=".$db->quote($sheetalias)." AND psp.alias=".$db->quote($pattern)." AND psp.answer=1";
   		$db->setQuery($query);
   
   		return $db->loadObject();
   	}
   }

   /**
    * Set user's primary phone number
    * @param  bool  $is_mobile Set true if called by mobile api
    * @return bool
    */
   public function setPrimaryMobile($is_mobile=false) {
      // Simple security check
      if(!$is_mobile && !PSession::checkToken()) {
         $this->setErrorCode(20004);
         $this->setError('登录已失效，请重新登录');
         return false;
      }

      if(!PFactory::isJobseekerUser()) {
         $this->setErrorCode(20006);
         $this->setError("您无权访问该资源");
         return false;
      }

      $me = PFactory::getUser();
      $userid = JRequest::getInt("uid", 0);
      $userid = $userid ? $userid : $me->id;
      $isOwner = $me->id == $userid;
      $puser = $this->loadUser($userid);
      if(!$puser) {
         $this->setErrorCode(20007);
         $this->setError("用户不存在");
         return false;
      }

      $post = JRequest::get('post');

      // validate current password
      $parts   = explode( ':', $puser->password );
      $crypt   = $parts[0];
      $salt = @$parts[1];
      $testcrypt = JUserHelper::getCryptedPassword($post['password'], $salt);

      if($crypt != $testcrypt) {
         $this->setErrorCode(20008);
         $this->setError("当前密码错误");
         return false;
      }

      if (!JobHelper::isPhone($post['mobile'])) {
         $this->setErrorCode(40023);
         $this->setError('请输入正确的联系电话');
         return false;
      }

      // Password check pass
      $db = PFactory::getDbo();
      $query = "INSERT INTO #__users_mobile SET userid = ".intval($userid).", mobile = ".$db->quote($post['mobile']).", `primary` = 1 ON DUPLICATE KEY UPDATE userid=values(userid),mobile=values(mobile),`primary`=values(`primary`)";
      $db->setQuery($query);

      if (!$db->execute()) {
         $this->setErrorCode(20012);
         $this->setError("设置登录手机号失败, 请重试");
         return false;
      }

      $query = "UPDATE #__users_mobile SET `primary` = 0 WHERE userid = ".intval($userid)." AND mobile <> ".$db->quote($post['mobile']);
      $db->setQuery($query);
      $db->execute();

      return true;
   }
}
